using System;
using System.Linq;
using Granite.Metadata;
using System.ComponentModel;
using System.Xml.Linq;
using Granite.Modeling;
using Granite.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Toon.Models.Characters
{
	public class Skill : ChangeTrackingModelBase
	{
		readonly Attribute m_Attribute;
		readonly string m_Name;
		public Skill(Attribute attribute, string name)
		{
			m_Name = name;
			m_Attribute = attribute;
		}

		public string Name
		{
			get { return m_Name; }
		}

		/// <summary>
		/// This tracks the number of skill points spent.
		/// </summary>
		public int SkillPoints
		{
			get { return Get<int>("SkillPoints"); }
			set { Set(value, "SkillPoints"); }
		}

		/// <summary>
		/// This tracks the number of plot points spent.
		/// </summary>
		public int PlotPoints
		{
			get { return Get<int>("PlotPoints"); }
			set { Set(value, "PlotPoints"); }
		}

		[CalculatedField("SkillPoints")]
		[CalculatedField("PlotPoints")]
		public int SkillLevel
		{
			get { return (PlotPoints / 2) + SkillPoints + m_Attribute.Value; }
		}

		protected override void OnValidateProperty(string propertyName, ValidationResultCollection results)
		{
			base.OnValidateProperty(propertyName, results);

			switch (propertyName)
			{
				case "SkillPoints":
					if (SkillPoints < 0)
						results.Add("Skill points cannot be less than 0.", "SkillPoints");
					break;

				case "PlotPoints":
					if (PlotPoints < 0)
						results.Add("Plot points cannot be less than 0.", "PlotPoints");
					break;
			}
		}

		protected override void OnValidateObject(ValidationResultCollection results)
		{
			base.OnValidateObject(results);

			if (SkillLevel > 9)
				results.Add("The skill level cannot exceed 9. Reduce the number of plot points or skill points spend on this skill", "PlotPoints", "SkillPoints");
		}


		internal void AttributePropertyChanged(PropertyChangedEventArgs args)
		{
			if (args.PropertyName == "Value")
				OnPropertyChanged("SkillLevel");
		}

		internal XElement ToXml()
		{
			return new XElement("Skill",
					   new XAttribute("Name", Name),
					   new XAttribute("SkillPoints", SkillPoints),
					   new XAttribute("PlotPoints", PlotPoints));
		}

		internal void FromXml(XElement source)
		{
			SkillPoints = int.Parse(source.Attribute("SkillPoints").Value);
			PlotPoints = int.Parse(source.Attribute("PlotPoints").Value);
		}

		public override string ToString()
		{
			return string.Format("{0} {1}", Name, SkillLevel);
		}
	}
}
